﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using ClearingRestartingAutomaton.Base;

namespace ClearingRestartingAutomaton
{
    public partial class LearningForm : Form
    {
        public LearningForm()
        {
            this.automatonLearning = new AutomatonLearning();
            InitializeComponent();
        }

        private string initialWord;
        private string leftContext;
        private string rightContext;
        private AutomatonLearning automatonLearning;

        private bool ReadInitialConditions(bool showMessages)
        {
            string patt_initialWord = @"^[a-zA-Z0-9@#%]*$";
            string patt_leftContext = @"^\^[a-zA-Z0-9@#%]*$";
            string patt_rightContext = @"^[a-zA-Z0-9@#%]*\$$";
            if (Regex.IsMatch(initialWordTextBox.Text, patt_initialWord))
                this.initialWord = initialWordTextBox.Text;
            else
            {
                if (showMessages)
                    MessageBox.Show("Initial word does not match the pattern.", "Warning");
                return false;
            }
            if (Regex.IsMatch(leftContextTextBox.Text, patt_leftContext))
                this.leftContext = leftContextTextBox.Text;
            else
            {
                if (showMessages)
                    MessageBox.Show("Left context does not match the pattern.", "Warning");
                return false;
            }
            if (Regex.IsMatch(rightContextTextBox.Text, patt_rightContext))
                this.rightContext = rightContextTextBox.Text;
            else
            {
                if (showMessages)
                    MessageBox.Show("Right context does not match the pattern.", "Warning");
                return false;
            }
            return true;
        }

        private void startButton_Click(object sender, EventArgs e)
        {
            if (ReadInitialConditions(true))
            {
                this.automatonLearning.Steps.Clear();
                learningProcessRichTextBox.Clear();
                learningStepTextBox.Text = this.initialWord;
                learningProcessRichTextBox.AppendText(this.initialWord);
            }
        }

        private void appendButton_Click(object sender, EventArgs e)
        {
            if (ReadInitialConditions(true))
            {
                learningStepTextBox.Text = this.initialWord;
                learningProcessRichTextBox.AppendText("\r\n");
                learningProcessRichTextBox.AppendText(this.initialWord);
            }
        }

        private void ReduceTo(string reduction)
        {
            System.Drawing.Font normalFont = learningProcessRichTextBox.Font;
            System.Drawing.Font underlinedFont = new System.Drawing.Font(
                normalFont.FontFamily, normalFont.Size, System.Drawing.FontStyle.Underline);
            if (learningStepTextBox.SelectionLength > 0)
            {
                string word = learningStepTextBox.Text;
                int startIndex = learningStepTextBox.SelectionStart;
                int length = learningStepTextBox.SelectionLength;
                string left = word.Substring(0, startIndex);
                string right = word.Substring(startIndex + length);
                LearningStep learningStep = new LearningStep(
                    word, startIndex, length, reduction, this.leftContext, this.rightContext);
                this.automatonLearning.Steps.Add(learningStep);
                learningProcessRichTextBox.SelectionStart =
                    learningProcessRichTextBox.Text.Length - word.Length + startIndex;
                learningProcessRichTextBox.SelectionLength = length;
                learningProcessRichTextBox.SelectionFont = underlinedFont;
                learningProcessRichTextBox.SelectionStart = learningProcessRichTextBox.Text.Length;
                learningProcessRichTextBox.SelectionLength = 0;
                learningProcessRichTextBox.SelectionFont = normalFont;
                learningProcessRichTextBox.SelectionColor = System.Drawing.Color.Black;
                learningProcessRichTextBox.AppendText(" -> \r\n");
                learningProcessRichTextBox.AppendText(left);
                learningProcessRichTextBox.SelectionColor = Color.Red;
                learningProcessRichTextBox.AppendText(reduction);
                learningProcessRichTextBox.SelectionColor = Color.Black;
                learningProcessRichTextBox.AppendText(right);
                learningProcessRichTextBox.SelectionStart = learningProcessRichTextBox.Text.Length;
                learningProcessRichTextBox.SelectionLength = 0;
                learningProcessRichTextBox.SelectionFont = normalFont;
                learningProcessRichTextBox.SelectionColor = System.Drawing.Color.Black;
                learningStepTextBox.Text = left + reduction + right;
            }
        }

        private void reduceButton_Click(object sender, EventArgs e)
        {
            this.ReduceTo("");
        }

        private void reduceSharpButton_Click(object sender, EventArgs e)
        {
            this.ReduceTo("#");
        }

        private void reduceToTextButton_Click(object sender, EventArgs e)
        {
            string patt_reduction = @"^[a-zA-Z0-9@#%]*$";
            if (Regex.IsMatch(reductionTextBox.Text, patt_reduction))
                this.ReduceTo(reductionTextBox.Text);
            else MessageBox.Show("Reduction word does not match the pattern.", "Warning");
        }

        private void generateButton_Click(object sender, EventArgs e)
        {
            Automaton automaton = this.automatonLearning.GetAutomaton((int)kNumericUpDown.Value);
            InformationForm infoForm = new InformationForm(automaton.ToString());
            infoForm.Show();
        }

    }
}
